package gsw.tool.ui;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapRegionDecoder;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Scroller;

import java.io.IOException;
import java.io.InputStream;

/**
 * TODO 只考虑长图，不考虑横图
 * Created by siwei on 2018/1/16.
 */

public class BigView extends View implements GestureDetector.OnGestureListener, View.OnTouchListener {
    private Bitmap mBitmap;//要加载的位图
    private Rect mRect;//指定加载的矩形区域
    private BitmapFactory.Options mOptions;//解码图片的配置
    private BitmapRegionDecoder mDecoder;//大图解码器
    private Scroller mScroller;//滑动器
    private GestureDetector mDetector;//手势管理

    private int mImageWidth;//图片宽
    private int mImageHeight;//图片高
    private int mViewWidth;//控件宽
    private int mViewHeight;//控件高
    private float mSacle;//缩放因子

    public BigView(Context context) {
        this(context, null);
    }

    public BigView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public BigView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mRect = new Rect();
        mOptions = new BitmapFactory.Options();
        mScroller = new Scroller(context);
        mDetector = new GestureDetector(context, this);
        setOnTouchListener(this);
    }

    /**
     * 设置图片
     *
     * @param is 图片的输入流
     */
    public void setImage(InputStream is) {
        mOptions.inJustDecodeBounds = true;//加载边框
        BitmapFactory.decodeStream(is, null, mOptions);//获取图片宽高
        mImageWidth = mOptions.outWidth;
        mImageHeight = mOptions.outHeight;
        mOptions.inMutable = true;//复用Bitmap TODO
        mOptions.inPreferredConfig = Bitmap.Config.RGB_565;//设置像素格式
        mOptions.inJustDecodeBounds = false;//加载图片
        try {
            mDecoder = BitmapRegionDecoder.newInstance(is, false);//isShareable为false会复制一张图片，为true会共用
        } catch (IOException e) {
            e.printStackTrace();
        }
        requestLayout();//重新布局
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        if (mDecoder == null) {
            return;
        }

        mViewWidth = getMeasuredWidth();//测量控件的宽
        mViewHeight = getMeasuredHeight();//测量控件的高
        mSacle = (float) mViewWidth / mImageWidth;

        //获取加载区域
        mRect.left = 0;
        mRect.top = 0;
        mRect.right = mImageWidth;
        mRect.bottom = (int) (mViewHeight / mSacle);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (mDecoder == null) {
            return;
        }
        mOptions.inBitmap = mBitmap;//复用mBitmap
        mBitmap = mDecoder.decodeRegion(mRect, mOptions);
        Matrix matrix = new Matrix();//通过矩阵缩放
        matrix.setScale(mSacle, mSacle);//设置水平和垂直方向的缩放
        canvas.drawBitmap(mBitmap, matrix, null);
    }

    @Override
    public boolean onDown(MotionEvent e) {
        if (!mScroller.isFinished()) {//滑动没停止
            mScroller.forceFinished(true);//强制结束
        }
        return true;//接收后续事件
    }

    @Override
    public void onShowPress(MotionEvent e) {

    }

    @Override
    public boolean onSingleTapUp(MotionEvent e) {
        return false;
    }

    /**
     * 重写onScroll，调整图片的矩阵显示区域
     */
    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
        mRect.offset(0, (int) distanceY);//垂直滑动图片
        if (mRect.bottom > mImageHeight) {
            mRect.top = (int) (mImageHeight - mViewHeight / mSacle);
            mRect.bottom = mImageHeight;
        }
        if (mRect.top < 0) {
            mRect.top = 0;
            mRect.bottom = (int) (mViewHeight / mSacle);
        }
        invalidate();//重绘
        return false;
    }

    @Override
    public void onLongPress(MotionEvent e) {

    }

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        mScroller.fling(
                0,//滑动开始的x坐标
                mRect.top,//滑动开始的y坐标
                0, //水平速度
                (int) -velocityY,//垂直速度
                0,//X方向移动的最小距离
                0,//X方向移动的最大距离
                0,//Y方向移动的最小距离
                (int) (mImageHeight - mViewHeight / mSacle)//Y方向移动的最大距离
        );
        return false;
    }

    /**
     * 滑动
     */
    @Override
    public void computeScroll() {
        if (mScroller.isFinished()) {//滑动结束
            return;
        }
        if (mScroller.computeScrollOffset()) {//滑动进行中
            mRect.top = mScroller.getCurrY();
            mRect.bottom = (int) (mRect.top + mViewHeight / mSacle);
            invalidate();
        }
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        return mDetector.onTouchEvent(event);//交由手势处理
    }
}
